using System;
using System.Collections.Generic;
using System.Text;
using FireStarter.Base;
using FireStarter.CodeGeneration;
using FireStarter.CodeGeneration.Generator;
using FireStarterModeller.BO;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration.Generator
{
    [TestFixture]
    public class TestForEachExpression
    {
        [Test]
        public void Test_ForEachExpression_Creation()
        {
            //---------------Set up test pack-------------------
            //<<|FOREACH(IModelPropDefs):
            //		test; 
            //
            //|>>

            const string imodelpropdefs = "IModelPropDefs";

            ForEachExpression forEachExpression = new ForEachExpression(imodelpropdefs);
            LiteralExpression literalExpression = new LiteralExpression(" test; \n");

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            forEachExpression.Part = literalExpression;
            //---------------Test Result -----------------------

            Assert.AreSame(literalExpression, forEachExpression.Part);
            Assert.IsNull(forEachExpression.Next);
            Assert.AreEqual(imodelpropdefs, forEachExpression.CollectionName);
        }

        [Test]
        public void Test_ForEachExpression_Generation()
        {
            //---------------Set up test pack-------------------
            //<<|FOREACH(IModelPropDefs):
            //test; |>>
            const string imodelpropdefs = "IModelPropDefs";
            ForEachExpression forEachExpression = new ForEachExpression(imodelpropdefs);
            const string literal = "test; ";
            LiteralExpression literalExpression = new LiteralExpression(literal);
            forEachExpression.Part = literalExpression;

            GenerationStrategyStub strategyStub = new GenerationStrategyStub();
            strategyStub.SetCollection(imodelpropdefs, new List<IModelElement> { new ModelElementStub(), new ModelElementStub() });

            var modelStrategyMapper = new ModelStrategyMapper();
            modelStrategyMapper.SetStrategy(typeof(ModelElementStub), strategyStub);

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            string result = forEachExpression.Generate(modelStrategyMapper, new ModelElementStub());
            //---------------Test Result -----------------------

            Assert.AreEqual(literal + literal, result);
        }


        [Test]
        public void Test_ForEachExpression_Generation_WithComplexPart()
        {
            //---------------Set up test pack-------------------
            //<<|FOREACH(IModelPropDefs):
            //<<|=PropName|>>;
            //|>>

            const string imodelpropdefs = "IModelPropDefs";
            const string literal = ";\n";
            const string propname = "PropName";
            ValueExpression valueExpression1 = new ValueExpression(propname);

            ForEachExpression forEachExpression = new ForEachExpression(imodelpropdefs);
            LiteralExpression literalExpression = new LiteralExpression(literal);
            valueExpression1.Next = literalExpression;
            forEachExpression.Part = valueExpression1;

            var strategyStub = new GenerationStrategyStub();
            var propname1Value = "PropName1";
            var propname2Value = "PropName2";
            var modelPropertyStub1 = new ModelPropertyStub(propname1Value);
            var modelPropertyStub2 = new ModelPropertyStub(propname2Value);
            strategyStub.SetCollection(imodelpropdefs, new List<IModelElement>
                                                           {
                                                               modelPropertyStub1,
                                                               modelPropertyStub2
                                                           });

            var modelStrategyMapper = new ModelStrategyMapper();
            modelStrategyMapper.SetStrategy(typeof(IModelClass), strategyStub);

            var modelPropertyStrategyStub = new GenerationPropertyStrategyStub();
            modelStrategyMapper.SetStrategy(typeof(IModelProperty), modelPropertyStrategyStub);
            IModelClass dmClass = new DMClass();
            //---------------Execute Test ----------------------

            string result = forEachExpression.Generate(modelStrategyMapper, dmClass);

            //---------------Test Result -----------------------
            Assert.AreEqual(propname1Value + literal + propname2Value + literal, result);
            Assert.AreSame(dmClass, strategyStub.ModelElement);
        }
    }
}
